// #include "mid_S32kToAutoChip_Hal.h"

#include "mid_sysbackup.h"
//#include "mid_clock.h"
#include "mid_debug.h"
#include "FlashConfig.h"
#include "eep_drv.h"

// flash_ssd_config_t flashSSDConfig;

/* ==========================================  Variables  =========================================== */
const Eep_ConfigType eep_config = {
    .EepSize          = USER_EEP_SIZE,           /* User-defined Memory Size                                               */
    .EepRamBaseAddr   = USER_EEP_RAMBASEADDR,    /* Base Address of SRAM in Use (Not Recommended for Use Except for EEPROM */
    .EepFlashBaseAddr = USER_EEP_FLASHBASEADDR,  /* Base Address of FLASH in Use (Not Recommended for Use Except for EEPROM*/
    .FlashPageSize    = USER_EEP_PAGESIZE,       /* FLASH Page Size, Fixed Chip Property                                   */
    .FlashMinProByte  = USER_EEP_MINPROBYTE,     /* Minimum Programming Unit of FLASH, Fixed Chip Property                 */
    .IcType           = EEP_AC78036,             /* Chip Model                                                             */
    .CallbackType     = NULL,                    /* Callback Function, Set by User, Invoked When Logical Block is Changed  */
};

#define LogMask_Backup  ((ELOG_Error | ELOG_Warning | ELOG_Trace) & LogMask_Globle)

#define backup_log(type, formate, ...) if ((type) & LogMask_Backup) DBUG_OUT(type, "Backup_log", formate, ##__VA_ARGS__)

struct_sysbackup_t g_sysbackup __attribute__((aligned(4)));

static bool sysbackup_init_flag = FALSE;

static bool mid_sysbackupIsActive(void){
	mid_sysbackup_readItem((uint32_t)&g_sysbackup.firstUseFlag, sizeof(g_sysbackup.firstUseFlag));
	return ((g_sysbackup.firstUseFlag == EEP_ACTIVE_FLAG) ? TRUE : FALSE);
}

void mid_sysbackup_ConfigDefaultValue(void){
	uint32_t size = 0;
	g_sysbackup.firstUseFlag = EEP_ACTIVE_FLAG;
	mid_sysbackup_writeItem((uint32_t)&g_sysbackup.firstUseFlag, sizeof(g_sysbackup.firstUseFlag));
}

uint32_t mid_sysbackup_init(void)
{
	uint32_t ret = E_OK;
    Eep_StatusType st = EEP_SUCCESS;

	st = Eep_Hal_Init(&eep_config);

	if(EEP_SUCCESS != st){
        ret = E_NOT_OK;
        backup_log(ELOG_Trace, "LINE[%d] : EEP_Init fail, st=%d...\r\n", __LINE__, st);
    }else{
		sysbackup_init_flag=true;
		if(mid_sysbackupIsActive() == FALSE){
			st = Eep_Hal_Erase(); 
			if(EEP_SUCCESS != st)
			{
				ret = E_NOT_OK;
			}else{
				mid_sysbackup_ConfigDefaultValue();
			}
		}
		mid_sysbackup_readall();
	}

    return ret;
}


void mid_sysbackup_varinit(void)
{
	// ECUSoftwareVersionNumber();
}

uint32_t mid_sysbackup_deinit(void)
{
	return E_OK;
}
uint32_t mid_sysbackup_readall(void)
{
	uint32_t ret = E_OK;
	Eep_StatusType st = EEP_SUCCESS;

	if(sysbackup_init_flag == FALSE){
		mid_sysbackup_init();
	}

	st =  Eep_Hal_Read(sysbackup_eep_start_addr, (uint8_t*)&g_sysbackup, sizeof(g_sysbackup));

	if(EEP_SUCCESS != st)
    {
        ret = E_NOT_OK;
        backup_log(ELOG_Trace, "LINE[%d] : EEP_Read fail, st=%d...\r\n", __LINE__, st);
    }
	ret = E_OK;

	return ret;
}
typedef union{
	struct_sysbackup_t data_struct;
	uint8_t data_array[FLASH_SECTOR_SIZE];
}backup_data_t;

static uint32_t mid_sysbackup_ReadWriteItem(uint32_t addr, uint32_t size, uint8_t rw){
	uint32_t ret = E_OK;
	Eep_StatusType st = EEP_SUCCESS;
	uint32_t addroffset = 0;

    if(sysbackup_init_flag==FALSE){
        mid_sysbackup_init();
    }

    if(rw!=0 && rw!=1)
        return E_NOT_OK;

	if ((addr < (uint32_t)(&g_sysbackup)) || (addr > ((uint32_t)(&g_sysbackup) + sizeof(g_sysbackup))))
	{
		st++;
	}
	if ((addr + size) > ((uint32_t)(&g_sysbackup) + sizeof(g_sysbackup)))
	{
		st++;
	}

	if (st > EEP_SUCCESS)
	{
		backup_log(ELOG_Trace, "[FLASH]%s Flash Failed!\r\n", (rw ? "Write" : "Read"));
		return E_NOT_OK;
	}

	addroffset = (uint32_t)(addr - (uint32_t)(&g_sysbackup));
    if(rw){
		st = Eep_Hal_Write(addroffset, &g_sysbackup.data_array[addroffset], size);
    }else{
        st = Eep_Hal_Read(addroffset,  &g_sysbackup.data_array[addroffset], size);
    }

    if(EEP_SUCCESS != st)
    {
        ret = E_NOT_OK;
        backup_log(ELOG_Trace, "LINE[%d] : %s Item fail, st=%d...\r\n", __LINE__, (rw ? "Write" : "Read"), st);
    }
	return ret;
}

uint32_t mid_sysbackup_writeItem(uint32_t addr, uint32_t size)
{
    return mid_sysbackup_ReadWriteItem(addr, size, 1);
}

uint32_t mid_sysbackup_readItem(uint32_t addr, uint32_t size){
    return mid_sysbackup_ReadWriteItem(addr, size, 0);
}

uint32_t mid_sysbackup_writeall(void)
{
	uint32_t ret = E_OK;
    Eep_StatusType st = EEP_SUCCESS;

	 if(sysbackup_init_flag==false){
        mid_sysbackup_init();
    }

	st = Eep_Hal_Write(sysbackup_eep_start_addr, (uint8_t*)&g_sysbackup, sizeof(g_sysbackup));

	if(EEP_SUCCESS != st)
    {
        ret = E_NOT_OK;
        backup_log(ELOG_Trace, "LINE[%d] : EEP_Write fail, st=%d...\r\n", __LINE__, st);
    }

	backup_log(ELOG_Trace, "[FLASH]write all data from flash\r\n");
	
	return ret;
}

void SRAM_WriteProgrammingSessionFlag(void)                        
{     
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 0) = 0x50u; /* 'P' */
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 1) = 0x72u; /* 'r' */ 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 2) = 0x6Fu; /* 'o' */
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 3) = 0x67u; /* 'g' */  
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 4) = 0x53u; /* 'S' */ 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 5) = 0x69u; /* 'i' */  
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 6) = 0x67u; /* 'g' */ 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 7) = 0x6Eu; /* 'n' */ 	
}

void SRAM_WriteEcuResetFlag(void)                        
{     
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 0) = 0x72u; /* 'r' */
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 1) = 0x65u; /* 'e' */ 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 2) = 0x73u; /* 's' */
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 3) = 0x65u; /* 'e' */  
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 4) = 0x74u; /* 't' */ 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 5) = 0x69u; /* 'i' */  
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 6) = 0x6Eu; /* 'n' */ 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 7) = 0x67u; /* 'g' */ 	
}

void SRAM_WriteEnterAppFlag(void)                        
{     
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 0) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 1) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 2) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 3) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 4) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 5) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 6) = 0u; 
	*(uint8_t *)(TEMPORARY_FLAG_BASE + 7) = 0u; 
}

uint8_t mid_sysbackup_ClearAll(void)
{
	//status_t ret = STATUS_ERROR;        /* Store the driver APIs return code */
//   uint32_t address;
//   uint8_t data[8]={0,0,0,0,0,0,0,0};
// 	/* Try to write data to EEPROM if FlexRAM is configured as EEPROM */
//     if (flashSSDConfig.EEESize != 0u)
//     {
//         address = flashSSDConfig.EERAMBase;

//         for(uint32_t i=0; i<4096; i+=8)
//         {
//           ret = FLASH_DRV_EEEWrite(&flashSSDConfig, address+i, 8, data);
//           if (ret != STATUS_SUCCESS)
//           {
//               return ret;
//           }
//         }
//     }
	//return (uint8_t)ret;
}

